﻿// Copyright 2009 Mike Geise
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Falcon.Forums.Controllers
{
	using System.Web.Mvc;
	using Falcon.Core.Controllers;
	using Falcon.Core.Domain.Enums;
	using Falcon.Core.Domain.Services;
	using Falcon.Core.Extensions;
	using Falcon.Core.Validation;
	using Falcon.Forums.Domain;
	using Falcon.Forums.Domain.Enums;
	using Falcon.Forums.Domain.Services;
	using Falcon.Forums.Domain.Values;

	public class ForumTopicController : DefaultController
	{
		public ForumTopicController(
			IForumService forumService,
			IForumPermissionService forumPermissionService, 
			IForumTopicService forumTopicService,
			IForumTopicTagService forumTopicTagService,
			IForumPostService forumPostService,
			IAttachmentStoreService attachmentStoreService)
		{
			this.ForumService = forumService;
			this.ForumPermissionService = forumPermissionService;
			this.ForumTopicService = forumTopicService;
			this.ForumTopicTagService = forumTopicTagService;
			this.ForumPostService = forumPostService;
			this.AttachmentStoreService = attachmentStoreService;
		}

		public IForumService ForumService
		{
			get; 
			private set;
		}

		public IForumPermissionService ForumPermissionService
		{
			get; 
			private set;
		}

		public IForumTopicService ForumTopicService
		{
			get;
			private set;
		}

		public IForumTopicTagService ForumTopicTagService
		{
			get;
			private set;
		}

		public IForumPostService ForumPostService
		{
			get;
			private set;
		}

		public IAttachmentStoreService AttachmentStoreService
		{
			get;
			private set;
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Index(int id, string slug, SortForumTopic sort, SortOrder order, int? page)
		{
			var forum = ForumService.GetById(id);

			if (forum == null)
			{
				return Error(ForumsResources.Messages.ForumNotFound);
			}

			if (!forum.CanViewForum)
			{
				return NotAuthorized();
			}

			forum.Topics = ForumTopicService.GetPaged(new ForumTopicSpecification
			{
				ForumId = forum.Id,
				Scope = ForumTopicScope.Normal,
				Sort = sort,
				Order = order,
				Page = page,
				Limit = ForumsSettings.Topics.PageLimit
			});

			ForumService.MarkRead(forum);

			return View(Views.Index, forum);
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Tagged(string slug, int? page)
		{
			var tags = ForumTopicTagService.GetPaged(new ForumTopicTagSpecification
			{
				Slug = slug,
				Page = page,
				Limit = ForumsSettings.Topics.PageLimit
			});

			return View(ForumsViews.Tagged, tags);
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Detail(int id, string slug, int? page)
		{
			var topic = ForumTopicService.GetById(id);

			if (topic == null)
			{
				return Error(ForumsResources.Messages.ForumTopicNotFound);
			}

			topic.Forum.Permissions = ForumPermissionService.GetAll(new ForumPermissionSpecification
			{
				ForumId = topic.Forum.Id
			});

			topic.Posts = ForumPostService.GetPaged(new ForumPostSpecification
			{
				TopicId = topic.Id, 
				Page = page, 
				Limit = ForumsSettings.Posts.PageLimit
			});

			return topic.Forum.CanViewAnyTopic || (topic.IsOwner && topic.Forum.CanViewTopic) ? View(Views.Detail, topic) : NotAuthorized();
		}

		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Poll(int id, string slug)
		{
			var topic = ForumTopicService.GetById(id);

			return topic == null ? Error(ForumsResources.Messages.ForumTopicNotFound) : View(ForumsViews.Poll, topic);
		}

		[AcceptVerbs(HttpVerbs.Get), Authorize]
		public ActionResult Create(int id)
		{
			var forum = ForumService.GetById(id);

			if (forum == null)
			{
				return Error(ForumsResources.Messages.ForumNotFound);
			}

			return forum.CanCreateTopic ? View(Views.Create, new ForumTopicCreate(forum)) : NotAuthorized();
		}

		[AcceptVerbs(HttpVerbs.Post), Authorize]
		public ActionResult Create(ForumTopicCreate value)
		{
			try
			{
				var forum = ForumService.GetById(value.ForumId);

				if (forum == null)
				{
					return Error(ForumsResources.Messages.ForumNotFound);
				}

				value.Forum = forum;

				if (!forum.CanCreateTopic)
				{
					return NotAuthorized();
				}

				value.Attachment.Source = Request.Files[0];

				if (AttachmentStoreService.Process(value.Attachments, value.Attachment))
				{
					return View(Views.Create, value);
				}

				var topic = ForumTopicService.Create();

				ForumTopicService.Insert(topic, value);

				return RedirectToRoute(ForumsRoutes.ForumTopicDetail, new { id = topic.Id, slug = topic.Slug });
			}
			catch (ValidationException exception)
			{
				ModelState.CopyValidationExceptions(exception);
			}

			return View(Views.Create, value);
		}
	}
}